
/**  
* @Title: AipSpeech.java
* @Package com.third.baidu.aip
* @Description: 
* @author likai
* @date 2018年1月3日
* @version V1.0  
*/

package com.third.utils.baidu;

import java.io.IOException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.baidu.aip.error.AipError;
import com.baidu.aip.http.AipHttpClient;
import com.baidu.aip.http.AipRequest;
import com.baidu.aip.http.AipResponse;
import com.baidu.aip.http.EBodyFormat;
import com.baidu.aip.http.Headers;
import com.baidu.aip.http.HttpContentType;
import com.baidu.aip.speech.TtsResponse;
import com.baidu.aip.util.AipClientConst;
import com.baidu.aip.util.Base64Util;
import com.baidu.aip.util.SignUtil;
import com.baidu.aip.util.Util;
import com.third.base.baidu.BaseClient;
import com.third.utils.baidu.AipSpeechConfig.Format;


/**
 * @ClassName: AipSpeech
 * @Description: 百度语音、人脸、词汇等识别:http://yuyin.baidu.com/docs/asr/57
 * @author likai
 * @date 2018年1月3日
 * 
 * 更多功能参考：
 * 		<dependency>
		    <groupId>com.baidu.aip</groupId>
		    <artifactId>java-sdk</artifactId>
		    <version>4.0.0</version>
		</dependency>
 *
 */

public class AipSpeechUtil extends BaseClient {
	public static Logger log = LoggerFactory.getLogger(AipSpeechUtil.class);
	private static final String SPEECH_ASR_URL = "http://vop.baidu.com/server_api";// 语音转文字
	private static final String SPEECH_TTS_URL = "http://tsn.baidu.com/text2audio";// 文字转语音
	private static AipSpeechUtil aipSpeech;
	private AipSpeechUtil(AipSpeechConfig baiduConfig) {
		super(baiduConfig.getAppId(), baiduConfig.getApiKey(), baiduConfig.getSecretKey());
	}

	public static AipSpeechUtil create(AipSpeechConfig baiduConfig) {
		if (aipSpeech==null) {
			aipSpeech=new AipSpeechUtil(baiduConfig);
		}
		return aipSpeech;
	}
	/* 
	    * @Description:语音转文字
	    * 
	    * @param:
	    * 
	    * filePath :语音文件路径
		* format:转换格式
	    *
	    */
	public String videoToText(String filePath, Format format) {
		try {
			byte[] imgData = Util.readFileByBytes(filePath);
			JSONObject result = asr(imgData, format.toString(), 16000);
			if ((Integer)result.get("err_no")==0) {
				JSONArray array=(JSONArray) result.get("result");
				StringBuilder text=new StringBuilder();
				for (int i = 0; i < array.length(); i++) {
					text.append(array.get(i));
				}
				return text.toString();
			}else {
				if ((Integer)result.get("err_no")==3301) {
					return "";
				}
				log.info(result.toString());
				return "SDK113";
			}
		} catch (IOException e) {
			log.error("语音文件找不到");
			return AipError.IMAGE_READ_ERROR.getErrorCode();
		} catch (JSONException e) {
			log.error("语音结果解析失败");
			return "SDK114";
		}
	}

	// 语音转文字
	private JSONObject asr(byte[] data, String format, int rate) throws JSONException {
		AipRequest request = new AipRequest();

		preOperation(request); // get access token
		if (this.isBceKey.get()) {
			// get access token failed!
			return Util.getGeneralError(AipClientConst.OPENAPI_NO_ACCESS_ERROR_CODE,
					AipClientConst.OPENAPI_NO_ACCESS_ERROR_MSG);
		}
		// state.setState(EAuthState.STATE_TRUE_AIP_USER);
		String base64Content = Base64Util.encode(data);
		request.addBody("speech", base64Content);
		request.addBody("format", format);
		request.addBody("rate", rate);
		request.addBody("channel", 1);
		String cuid = SignUtil.md5(accessToken, "UTF-8");
		request.addBody("cuid", cuid);
		request.addBody("token", accessToken);
		request.addBody("len", data.length);
		//request.addBody("lan", "en");
		request.setUri(SPEECH_ASR_URL);
		request.setBodyFormat(EBodyFormat.RAW_JSON);
		request.addHeader(Headers.CONTENT_TYPE, HttpContentType.JSON_DATA);

		return requestServer(request);
	}

	// 文字转语音
	public TtsResponse synthesis(String text, String lang, int ctp) throws JSONException {
		AipRequest request = new AipRequest();
		preOperation(request);
		if (this.isBceKey.get()) {
			// get access token failed!
			TtsResponse response = new TtsResponse();
			JSONObject msg = Util.getGeneralError(AipClientConst.OPENAPI_NO_ACCESS_ERROR_CODE,
					AipClientConst.OPENAPI_NO_ACCESS_ERROR_MSG);
			response.setResult(msg);
			return response;
		}
		request.addBody("tex", text);
		request.addBody("lan", lang);
		request.addBody("tok", accessToken);
		request.addBody("ctp", ctp);
		String cuid = SignUtil.md5(accessToken, "UTF-8");
		request.addBody("cuid", cuid);

		request.setUri(SPEECH_TTS_URL);

		TtsResponse response = new TtsResponse();
		AipResponse res = AipHttpClient.post(request);
		if (res == null) {
			response.setResult(Util.getGeneralError(-1, "null response from server"));
			return response;
		}
		String contentType = res.getHeader().get("Content-type").get(0);
		if (contentType.contains("json")) {
			String data = res.getBodyStr();
			JSONObject json = new JSONObject(data);
			response.setResult(json);
			return response;
		}
		byte[] binData = res.getBody();
		response.setData(binData);

		return response;
	}

}
